#ifndef POOL_H
#define POOL_H

#include <iostream>
#include <thread>
#include <map>
#include <queue>
#include <mutex>
#include <semaphore.h>
#include <atomic> // 原子性变量

using namespace std;

#define TASE_QUEUE_SIZE 3  // 线程池任务队列大小  队列中任务数量超过这个大小，就会创建新线程

/* 
    线程基类

    所有的用户自定义的任务线程必须实现这个基类，重写 run 方法
*/
class I_Thread {
public:
    I_Thread() {}
    virtual ~I_Thread() {}

    virtual void run() = 0;
};

/* 线程池 管理者线程所需枚举 */
enum Mode {
    EMPTY, // 初始值
    TASK // 为线程分配任务
};

/* 线程池 */
class ThreadPool final {
public:
    ThreadPool(int core, int max);
    ~ThreadPool();

    void addTask(I_Thread* task); // 添加任务
private:
    int core; // 核心线程数
    int max; // 最大线程数
    atomic<int> cur; // 当前线程数  atomic保证原子性
    atomic<int> leisure; // 空闲线程数
    queue<I_Thread*> taskQueue; // 任务队列没有满的概念，可以一直来任务，处理任务交给管理者线程
    mutex mutexLock; // 任务队列锁
    sem_t sem_task; // 任务队列的信号量，记录队列中有多少任务
    map<std::thread::id,thread*> taskThread; // 所有的工作线程 std::thread::id是线程id
    thread* managerThread; // 管理者线程
    sem_t sem_manager; // 管理者线程的信号量
    atomic<int> mode; // 管理者线程的工作模式

    void task(); // 管理者线程，调度任务的方法
    void createThread(); // 创建工作线程
    void managerRun(); // 管理者线程执行的方法
    void exec(); // 工作线程执行的方法
};
#endif